package com.systar.activity.parse;

import java.io.IOException;
import java.net.URL;
import java.util.concurrent.atomic.AtomicInteger;

import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.easymock.IMocksControl;
import org.easymock.internal.Invocation;
import org.easymock.internal.LastControl;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;

import com.castsoftware.java.FileExplorer;
import com.castsoftware.java.FileExplorerMock;
import com.castsoftware.java.FileExplorerMock.FileMock;
import com.systar.activity.events.IActivityEvent;
import com.systar.activity.events.ParsingActivityEvent;
import com.systar.activity.monitor.ActivityManager;
import com.systar.activity.monitor.ActivitySource;

public class ParseEnvironment
{
	protected FileExplorerMock explorerMock;
	protected FileMock rootDir;

	@Before
	public void setUp()
	{
		/* When using the FileExplorer class for file system access, you are able to mock it for your tests 
		 * FileExplorerMock is able to configure a virtual file system with directories, files and file content 
		 * Set FileExplorerMock as instance for FileSystem */
		explorerMock = new FileExplorerMock();
		FileExplorer.setInstance(explorerMock);
		// create a FileMock for root directory
		rootDir = explorerMock.configure("C:/LOGS");

	}

	@After
	public void tearDown()
	{
		// Do not forget to remove mock for other tests
		FileExplorer.setInstance(null);
	}

	protected String getResourceContent(String resourceFileRelativePath)
	{
		URL jobFilePath = ParseEnvironment.class.getResource(resourceFileRelativePath);
		try
		{
			java.util.Scanner s = new java.util.Scanner(jobFilePath.openStream()).useDelimiter("\\A");
			return s.hasNext() ? s.next() : "";
		}
		catch (IOException e)
		{
			return "";
		}
	}

	protected void runTest(int expectedErrors, ParserBuilder builder) throws Exception
	{
		// create mocks
		IMocksControl control = EasyMock.createNiceControl();

		ActivityManager manager = control.createMock(ActivityManager.class);
		final AtomicInteger nbErrors = new AtomicInteger(0);
		manager.handleDisplayEvent(EasyMock.isA(IActivityEvent.class));
		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>()
		{
			@Override
			public Object answer()
			{
				final Invocation result = LastControl.getCurrentInvocation();
				IActivityEvent event = (IActivityEvent) result.getArguments()[0];
				if (event instanceof ParsingActivityEvent)
				{
					ParsingActivityEvent parseEvent = (ParsingActivityEvent)event;
					nbErrors.addAndGet(parseEvent.getNbErr());
				}
				return null;
			}

		}).atLeastOnce();
		
		ActivitySource source = new ActivitySource(manager, "name", "C:/LOGS");

		control.replay();

		// create parser and run it
		FileParser parser = builder.buildParser(manager, source);
		parser.call();

		// checks
		control.verify();
		Assert.assertEquals("Unexpected error count", expectedErrors, nbErrors.get());

	}
}
